package com.huawei.java.alogrithm;

import com.huawei.java.model.Graph;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @program: CodeCraft-2022
 * @description:
 * @author: hzy
 * @create: 2022-03-19 18:35
 **/
public class ResultOptimize {
//    class SiteAllocate {
//        //key 是clientName, value是向其分配的带宽
//        public Map<String, Integer> allocatedMap = new HashMap<>();
//        public int allocatedCount = 0;
//        public SiteAllocate(String clientName, Integer value) {
//            add(clientName, value);
//        }
//        public void add(String clientName, Integer value) {
//            allocatedMap.put(clientName, value);
//            allocatedCount++;
//        }
//    }

    public Map<String, Map<String, Integer>> optimize(Graph graph, Map<String, Map<String, Integer>> allocationMaps) {
//        //key是siteName, value是向客户分配的具体情况
//        Map<String, SiteAllocate> site = new HashMap<>();
//
//        for (Map.Entry<String, Map<String, Integer>> entry : allocationMaps.entrySet()) {
//            String clientName = entry.getKey();
//            //allocation key是siteName  value是site分配的带宽
//            for (Map.Entry<String, Integer> allocation : entry.getValue().entrySet()) {
//                if (site.containsKey(allocation.getKey())) {
//                    site.get(allocation.getKey()).add(clientName, allocation.getValue());
//                } else {
//                    site.put(allocation.getKey(), new SiteAllocate(clientName, allocation.getValue()));
//                }
//            }
//        }
        Map<String, Map<String, Integer>> newAllocationMaps = allocationMaps;

        for (Map.Entry<String, Map<String, Integer>> entry : allocationMaps.entrySet()) {
            //key是clientName  value是site分配方案
            String clientName = entry.getKey();
            Map<String, Integer> siteAllocate = entry.getValue();
            List<String> siteNameList = new ArrayList<>();
            List<Integer> siteAllocatedList = new ArrayList<>();
            Integer allocatedAll = 0;

            //对于clientName 而言  已有分配的sitename 和 值
            for (Map.Entry<String, Integer> allocation : siteAllocate.entrySet()) {
                siteNameList.add(allocation.getKey());
                siteAllocatedList.add(allocation.getValue());
                allocatedAll += allocation.getValue();
            }//for
            int aveValue = allocatedAll / siteNameList.size();


            //开始整合
            int first = 0;
            int i = 0;
            int j = 0;
            int second = 0;
            int iNewValue = 0;
            int jNewValue = 0;
            boolean b = false;
            while (true) {
                if (i == siteAllocatedList.size()) {
                    break;
                }
                if (b) {
                    //修改过
                    b = false;
                    siteAllocatedList.set(first, iNewValue);
                    siteAllocatedList.set(second - 1, jNewValue);
                }

                //循环找到比平均值大的点
                for (i = first; i < siteAllocatedList.size(); i++) {

                    int jurgeValue = siteAllocatedList.get(i);
                    if (jurgeValue > aveValue) {

                        //再到一个比平均值小的可以转移的点
                        for (j = second; j < siteAllocatedList.size(); j++) {
                            if (i == j)
                                continue;

                            int targetValue = siteAllocatedList.get(j);

                            if (targetValue < aveValue) {
                                String siteHighName = siteNameList.get(i);
                                String siteLowName = siteNameList.get(j);

                                //highsize 理想需要转移的数目
                                Integer highSize = jurgeValue - aveValue;

                                Integer lowTotal = graph.getSiteIdMap().get(siteLowName).getTotalBandwidth();
                                Integer lowLeft = graph.getSiteIdMap().get(siteLowName).getCurrentBandwidth();

                                Integer highTotal = graph.getSiteIdMap().get(siteHighName).getTotalBandwidth();
                                Integer highLeft = graph.getSiteIdMap().get(siteHighName).getCurrentBandwidth();


                                //最大能转移的数值
                                Integer maxTransSize = aveValue - targetValue;
                                Integer actualSize = Math.min(maxTransSize, highSize);
                                actualSize = Math.min(actualSize, lowLeft);
                                //转移
                                graph.getSiteIdMap().get(siteLowName).setCurrentBandwidth(lowLeft - actualSize);
                                graph.getSiteIdMap().get(siteHighName).setCurrentBandwidth(highLeft + actualSize);

                                //改变分配方案里的值
                                first = i;
                                second = j + 1;
                                iNewValue = jurgeValue - actualSize;
                                jNewValue = targetValue + actualSize;
                                b = true;
                                break;
                            }
                        }//for
                        if (b) {
                            break;
                        }
                    }
                }//for
            }//while

            for (int l = 0; l < siteAllocatedList.size(); l++) {
                newAllocationMaps.get(clientName).put(siteNameList.get(l), siteAllocatedList.get(l));
            }

        }//for

        return newAllocationMaps;

    }



}
